package data_operater

import (
	"fmt"
	"strings"
)

type DataGetter interface {
	GetData(data interface{}) (interface{}, error)
	GetPath() string
}

func NewDataGetter(path string) DataGetter {
	return &dataGetter{path: path}
}

type dataGetter struct {
	path string
}

func (d dataGetter) GetPath() string {
	return d.path
}

func (d dataGetter) GetData(data interface{}) (interface{}, error) {
	return GetData(d.path, data)
}

// GetData 获取数据
func GetData(path string, data interface{}) (interface{}, error) {
	if path == "" || strings.TrimSpace(path) == "" {
		return data, nil
	}

	stateMover := NewStateMoveManager(
		Start2FieldMove{},
		Op2OpMove{},
		OpEnd2FieldMove{},
		OpEnd2OpStartMove{},
		OpStart2FieldMove{},
		OpStart2OpEndMove{},
		Field2OpStartMove{},
		Field2FieldMove{},
	)
	tokens, err := parseToken(stateMover, path)
	if err != nil {
		return nil, err
	}
	// 解释token-责任链模式
	getters := make([]Getter, 0)
	for _, token := range tokens {
		switch token.tokenType {
		case Field:
			lastGetterIndex := len(getters) - 1
			if lastGetterIndex < 0 {
				getters = append(getters, NewPropGetter(token.value))
			} else {
				if lastGetterIndex != 0 && getters[lastGetterIndex].GetType() == GetterTypeMerge {
					// 上一个是merge节点，则加入到上个节点里
					newGetter := NewPropGetter(token.value)
					getters[lastGetterIndex].(MergeExt).AddGetter(newGetter)
				} else {
					newGetter := NewPropGetter(token.value)
					getters[lastGetterIndex].SetNext(newGetter)
					getters = append(getters, newGetter)
				}
			}
		case OpArray:
			lastGetterIndex := len(getters) - 1
			if lastGetterIndex < 0 {
				panic("解释器错误：数组操作符前getter栈为空")
			}
			lastGetter := getters[lastGetterIndex]
			if lastGetter.GetType() != GetterTypeMerge {
				// 包装一层数组的getter
				newGetter, err := NewArrayGetter(token.value, lastGetter)
				if err != nil {
					panic(fmt.Errorf("解析器错误：%s", err.Error()))
				}
				getters[lastGetterIndex] = newGetter
				// 重新设置上个getter的下游
				if lastGetterIndex != 0 {
					getters[lastGetterIndex-1].SetNext(newGetter)
				}
			} else {
				// 上一个节点是merge节点，说明array节点需要包装的是merge节点的最后一个节点
				lastGetter.(MergeExt).WrapLastGetter(func(getter Getter) Getter {
					newGetter, err := NewArrayGetter(token.value, getter)
					if err != nil {
						panic(fmt.Errorf("解析器错误：%s", err.Error()))
					}
					return newGetter
				})
			}

		case OpProp:
			continue
		case OpMergeField:
			// 属性合并, 只可能出现在最后一个节点，把后面的节点统统合并
			lastGetterIndex := len(getters) - 1
			lastGetter := getters[lastGetterIndex]
			if lastGetter.GetType() != GetterTypeMerge {
				newGetter := NewMergeGetter()
				newGetter.(MergeExt).AddGetter(lastGetter)
				getters[lastGetterIndex] = newGetter
				// 重新设置上个getter的下游
				if lastGetterIndex != 0 {
					getters[lastGetterIndex-1].SetNext(newGetter)
				}
			}
			// else 已经是merge节点了，直接跳过

		}
	}
	// 直接执行第一个getter
	result, err := getters[0].Get(data)
	if err != nil {
		return nil, err
	}
	return result, nil

}
